import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.exception.RarException.RarExceptionType;
import com.github.junrar.rarfile.FileHeader;

import java.io.*;
import java.nio.charset.Charset;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipUtil {

    /**
     *
     * @param zipFile
     *            To unzip the files
     * @param outputPath
     *            Extract the location
     */
    public static void  zipDecompressing(String zipFile, String outputPath)
            throws IOException {

        ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile), Charset.forName("GBK"));
        BufferedInputStream bis = new BufferedInputStream(zis);

        try {
            File fOut = null;
            ZipEntry entry = null;
            while ((entry = zis.getNextEntry()) != null && !entry.isDirectory()) {

                fOut = new File(outputPath, entry.getName());

                if (!fOut.exists()) {
                    (new File(fOut.getParent())).mkdirs();
                }

                FileOutputStream fos = new FileOutputStream(fOut);

                BufferedOutputStream bos = new BufferedOutputStream(fos);
                try {
                    int b;
                    while ((b = bis.read()) != -1) {
                        bos.write(b);
                    }
                }finally {
                    bos.close();
                    fos.close();
                }

            }
        }finally {
            bis.close();
            zis.close();
        }

    }



    /**
     * @param rarFileName rar file name
     * @param outFilePath output file path
     * @return success Or Failed
     * @author zhuss
     * @throws Exception
     */
    public static boolean  unrar(String rarFileName, String outFilePath)  throws  Exception{

        boolean flag = false;
        try  {
            Archive archive = new  Archive(new File(rarFileName));
            if(archive == null){
                throw new FileNotFoundException(rarFileName + " NOT FOUND!");
            }
            if(archive.isEncrypted()){
                throw new Exception(rarFileName + " IS ENCRYPTED!");
            }
            List<FileHeader> files =  archive.getFileHeaders();
            for (FileHeader fh : files) {
                if(fh.isEncrypted()){
                    throw new Exception(rarFileName + " IS ENCRYPTED!");
                }
                String fileName = fh.getFileNameW();
                if(fileName != null && fileName.trim().length() > 0){

                    StringBuilder saveFileName = new StringBuilder(outFilePath);

                    // 修复linux下,文件分隔符错误
                    String[] fileNames = fileName.split("\\\\");
                    if(fileNames != null && fileNames.length > 0){
                        for (String name :fileNames) {
                            saveFileName.append(File.separator).append(name);
                        }
                    }

                    File saveFile = new File(saveFileName.toString());
                    File parent =  saveFile.getParentFile();
                    if(!parent.exists()){
                        parent.mkdirs();
                    }
                    if(!saveFile.exists()){
                        saveFile.createNewFile();
                    }else if(saveFile.isDirectory()){
                        continue;
                    }
                    FileOutputStream fos = new FileOutputStream(saveFile);
                    try {
                        archive.extractFile(fh, fos);
                        fos.flush();
//                        fos.close();
                    } catch (RarException e) {
                        if(e.getType().equals(RarExceptionType.notImplementedYet)){
                        }
                    }finally{
                        fos.close();
                    }
                }
            }
            flag = true;
        } catch  (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return flag;
    }


}